package pe.gob.onp.util;

import java.util.Hashtable;
import java.util.List;

import javax.faces.component.UIColumn;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;

import com.icesoft.faces.component.ext.HtmlDataTable;

public class WidgetCreator {
	
	/**
	 * Crea la estructura completa para un HtmlDataTable.<br/>
	 * 1- Crea las columnas segun el orden enviado en el key 
	 * 	DATATABLE_HEADER_LIST del hashtable properties 
	 * 	  parametro<br/>
	 * 2- Por cada columna, se encarga de agregar un outputText que contendra
	 * 	  el valor de un atributo de un objeto perteneciente a la lista
	 *    enviado en el key DATATABLE_SOURCE_LIST<br/>
	 * @param properties hashtable con las propiedades necesarias para la 
	 * implementacion del datatable. Se requiere lo siguiente:<br/><br/>
	 * - DATATABLE_HEADER_LIST : lista con los textos de cabecera<br/>
	 * - DATATABLE_SOURCE_LIST : lista de objetos que poblara el datatable<br/>
	 * - DATATABLE_VAR : texto del atributo VAR del datatable<br/>
	 * - DATATABLE_NUMBER_ROWS : numero de filas por paginas<br/>
	 * - DATATABLE_WIDTH : texto con el valor del atributo WIDTH del 
	 *  datatable<br/>
	 * - DATATABLE_SOURCE_LIST_BINDING : texto con el valor del atributo 
	 *  VALUE del datable<br/>
	 * - DATATABLE_COLUMN_BINDING : texto con el valor del atributo VALUE 
	 *  del HtmlOutputText que se creara por cada fila y columna<br/>
	 *  - DATATABLE_PREFIX : texto con el valor del prefijo, el cual servira 
	 *  para armar el id de los componentes del datatable<br/>
	 * <br/>
	 * Todos estos valores son constantes que se encuentran dentro de la clase 
	 * {@link #Constantes}
	 * @return datatable con estructura creada (columnas, filas)
	 * @throws Exception
	 */
	public static HtmlDataTable crearDataTable(Hashtable properties) throws WidgetCreatorException{

		HtmlDataTable datatableList = new HtmlDataTable();
		List lstColumnas = (List)properties.get(Constante.
					DATATABLE_HEADER_LIST);
		List lstObjetos = (List)properties.get(Constante.
				DATATABLE_SOURCE_LIST);
		String var = (String)properties.get(Constante.DATATABLE_VAR);
		Integer nroFilasxPagina = (Integer)properties.get(Constante.
				DATATABLE_NUMBER_ROWS);
		String width = (String)properties.get(Constante.DATATABLE_WIDTH);
		String dataTableListBinding = (String)properties.get(Constante.
				DATATABLE_SOURCE_LIST_BINDING);
		Hashtable bindingXColumna = (Hashtable)properties.get(Constante.DATATABLE_COLUMN_BINDING);
		String prefijo = (String)properties.get(Constante.DATATABLE_PREFIX);
		
		//Se valida que todas las propiedades necesarias para la creacion 
		//tengan valores
		System.out.println("Se validan que todas las propiedades tengan valores");
		if(lstColumnas == null)
			throw new WidgetCreatorException("No se ha definido el atributo " +
					"DATATABLE_HEADER_LIST para el datatable");
		if(lstObjetos == null)
			throw new WidgetCreatorException("No se ha definido el atributo " +
					"DATATABLE_SOURCE_LIST para el datatable");
		if(var == null || var.equals(""))
			throw new WidgetCreatorException("No se ha definido el atributo DATATABLE_VAR " +
					"para el datatable");
		if(nroFilasxPagina == null || nroFilasxPagina.intValue() == 0)
			throw new WidgetCreatorException("No se ha definido el atributo " +
					"DATATABLE_NUMBER_ROWS para el datatable");
		if(width == null)
			throw new WidgetCreatorException("No se ha definido el atributo " +
					"DATATABLE_WIDTH para el datatable");
		if(bindingXColumna == null)
			throw new WidgetCreatorException("No se ha definido el atributo " +
					"DATATABLE_BINDING_X_COL para el datatable");
		if(prefijo == null || prefijo.equals(""))
			throw new WidgetCreatorException("No se ha definido el atributo " +
					"DATATABLE_PREFIX para el datatable");
		System.out.println("> Propiedades estan completas");
		
		System.out.println("Se crearan columnas de manera dinamica");
		//Se asignan:
		//- Numero de filas por pagina
		//- Atributo VAR
		//- Width
		//- Binding para la lista de objetos
		System.out.println("Se asignan principales atributos del datatable:");
		System.out.println("> ROWS = " + nroFilasxPagina.intValue());
		System.out.println("> VAR = " + var);
		System.out.println("> WIDTH = " + width);
		System.out.println("> DATATABLE_BINDING = " + dataTableListBinding);
		
		datatableList.setRows(nroFilasxPagina.intValue());
		datatableList.setVar(var);
		datatableList.setWidth(width);
		ValueBinding vbSourceList = FacesContext.getCurrentInstance().getApplication().
			createValueBinding(dataTableListBinding);
		datatableList.setValueBinding("value",vbSourceList);
		
		
		//Se itera la lstColumnas para construir las columnas del datatable
		System.out.println("Se crearan " + lstColumnas.size() + " columnas");
		for(int i=0;i<lstColumnas.size();i++){
			System.out.println("> Creando la columna " + (i+1));
			String nombreColumna = (String)lstColumnas.get(i);
			String columnaBinding = (String)bindingXColumna.get(nombreColumna);
			
			//Se crea la columna
			UIColumn columna = new UIColumn();
			columna.setId(prefijo + "Column" + i);
			
			//Por defecto, el tipo de componente por columna es HtmlOutputText 
			HtmlOutputText outputTextoHeader = new HtmlOutputText();
			outputTextoHeader.setId(prefijo +"HeaderColumn" + i);
			System.out.println(">> ID_HEADER = " + "header" + i);
			System.out.println(">> NOMBRE_HEADER = " + nombreColumna);
			outputTextoHeader.setValue(nombreColumna);
			//Se adiciona el texto como parte del header de la columna
			columna.setHeader(outputTextoHeader);
			
			HtmlOutputText outputValorColumna = new HtmlOutputText();
	        outputValorColumna.setId(prefijo + "OutTxt" + i);
	        System.out.println(">> ID_TEXTO = " + "htmlOutputText" + i);
	        System.out.println(">> TEXTO_BINDING = " + columnaBinding);
	        ValueBinding vbColumnaBinding = FacesContext.getCurrentInstance().
	        	getApplication().createValueBinding(columnaBinding);
	        outputValorColumna.setValueBinding("value", vbColumnaBinding);
	        //Se adiciona el valor que tendra para fila de la columna
	        columna.getChildren().add(outputValorColumna);
			
	        //Se agrega la columna como parte del datatable
			datatableList.getChildren().add(columna);
			System.out.println("> Se agrego la columna " + (i+1));
		}
		return datatableList;
	}

}
